package io.gitee.minelx.filesystem.provider;

import io.gitee.minelx.filesystem.Directory;
import io.gitee.minelx.filesystem.File;
import io.gitee.minelx.filesystem.Locator;
import io.gitee.minelx.filesystem.Path;
import io.gitee.minelx.filesystem.init.OpenPolicy;
import io.gitee.minelx.filesystem.values.PathDescription;
import io.gitee.minelx.filesystem.values.SchemeAndAuthority;
import io.gitee.minelx.filesystem.values.URI;

import java.util.Map;
import java.util.NoSuchElementException;

public class FSRegistry {

	private final Map<SchemeAndAuthority, FS> registry;

	private FSRegistry(Map<SchemeAndAuthority, FS> registry) {
		this.registry = registry;
	}

	public Path path(String uriAsText) {
		URI uri = URI.from(uriAsText);
		return determine(uri.schemeAndAuthority()).path(uri.path());
	}

	public File file(String uriAsText, OpenPolicy openPolicy) {
		URI uri = URI.from(uriAsText);
		return determine(uri.schemeAndAuthority()).file(uri.path(), openPolicy);
	}

	public Directory dir(String uriAsText, OpenPolicy openPolicy) {
		URI uri = URI.from(uriAsText);
		return determine(uri.schemeAndAuthority()).dir(uri.path(), openPolicy);
	}

	public Locator determine(SchemeAndAuthority schemeAndAuthority) {
		FS fs = registry.entrySet().stream()
				.filter(which -> which.getKey().equals(schemeAndAuthority))
				.map(Map.Entry::getValue)
				.findFirst().orElseThrow(() -> new NoSuchElementException("no scheme&authority: " + schemeAndAuthority.toText()));
		return fs.locate();
	}

	public static FSRegistry create(Map<SchemeAndAuthority, FS> registry) {
		return new FSRegistry(registry);
	}
}
